package org.dcarew.tado.views;

import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import org.dcarew.tado.TaDoPlugin;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.viewers.DecoratingLabelProvider;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IColorProvider;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.IFontProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.ViewPart;

import com.sun.syndication.feed.synd.SyndEntry;
import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.io.FeedException;
import com.sun.syndication.io.SyndFeedInput;
import com.sun.syndication.io.XmlReader;

// TODO: sort completed to bottome

// TODO: sort by date

// TODO: add an add button

// TODO: error reporting

/**
 * 
 * 
 * @author Devon Carew
 */
public class TaDoView
	extends ViewPart
{
	private TreeViewer			viewer;
	
	private Action				action1;
	private Action				action2;
	
	private static String 		FEED1 = "http://dcarew.tadalist.com/lists/1041103.rss?token=ce11666ad961375ed2987d7ff940b767";
	private static String 		FEED2 = "http://dcarew.tadalist.com/lists/1041106.rss?token=ce11666ad961375ed2987d7ff940b767";
	private static String		FEED3 = "http://dcarew.tadalist.com/lists/1041149.rss?token=ce11666ad961375ed2987d7ff940b767";
	
	
	public TaDoView()
	{
		
	}

	/**
	 * This is a callback that will allow us to create the viewer and initialize it.
	 */
	public void createPartControl(Composite parent)
	{
		viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
		viewer.setContentProvider(new FeedContentProvider());
		viewer.setLabelProvider(new DecoratingLabelProvider(new FeedLabelProvider(), null));
		
		makeActions();
		hookContextMenu();
		hookDoubleClickAction();
		contributeToActionBars();
		
		Job job = new Job("Update Ta-da view") {
			protected IStatus run(IProgressMonitor monitor)
			{
				updateUI(getFeedData());
				return Status.OK_STATUS;
			}
		};
		
		job.setSystem(true);
		job.schedule(1000);
	}

	protected List getFeedData()
	{
		String[] 	urls = new String[] { FEED1, FEED2, FEED3 };
		List 		feeds = new ArrayList();
		
		for (int i = 0; i < urls.length; i++)
		{
			try
			{
				URL url = new URL(urls[i]);
				
				SyndFeedInput input = new SyndFeedInput();
				feeds.add(new PathElement(input.build(new XmlReader(url))));
			}
			catch (Exception e)
			{
				e.printStackTrace();
			}
		}
		
		return feeds;
	}

	protected void updateUI(final List feeds)
	{
		Display.getDefault().asyncExec(new Runnable() {
			public void run() {
				viewer.setInput(feeds);
				viewer.expandToLevel(2);
			}
		});
	}

	private void hookContextMenu()
	{
		
	}

	private void contributeToActionBars()
	{
		IActionBars bars = getViewSite().getActionBars();
		
		fillLocalPullDown(bars.getMenuManager());
		fillLocalToolBar(bars.getToolBarManager());
	}
	
	private void fillLocalPullDown(IMenuManager manager)
	{
		
	}
	
	private void fillLocalToolBar(IToolBarManager manager)
	{
		manager.add(action1);
		manager.add(action2);
	}
	
	private void makeActions()
	{
		action1 = new Action() {
			public void run() {
				
			}
		};
		action1.setText("Action 1");
		action1.setToolTipText("Action 1 tooltip");
		action1.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_OBJS_INFO_TSK));

		action2 = new Action() {
			public void run() {
				
			}
		};
		action2.setText("Action 2");
		action2.setToolTipText("Action 2 tooltip");
		action2.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_OBJS_INFO_TSK));
	}

	protected void printFeed(String string)
	{
		try
		{
			URL url = new URL(string);
			
			SyndFeedInput input = new SyndFeedInput();
			SyndFeed feed = input.build(new XmlReader(url));
			
			System.out.println(feed);
		}
		catch (IOException ioe)
		{
			ioe.printStackTrace();
		}
		catch (FeedException fe)
		{
			fe.printStackTrace();
		}
	}

	private void hookDoubleClickAction()
	{
		viewer.addDoubleClickListener(new IDoubleClickListener() {
			public void doubleClick(DoubleClickEvent event) {
				//doubleClickAction.run();
			}
		});
	}

//	private void showMessage(String message)
//	{
//		MessageDialog.openInformation(viewer.getControl().getShell(), "TaDo", message);
//	}

	/**
	 * Passing the focus request to the viewer's control.
	 */
	public void setFocus()
	{
		viewer.getControl().setFocus();
	}
	
	private static class FeedContentProvider
		implements ITreeContentProvider
	{
		
		
		public FeedContentProvider()
		{
			
		}
		
		public Object[] getChildren(Object element)
		{
			if (element == null)
				return new Object[0];
			
			PathElement pe = (PathElement)element;
			
			if (pe.getData() instanceof SyndFeed)
			{
				SyndFeed feed = (SyndFeed)pe.getData();
				
				Object[] entries = feed.getEntries().toArray();
				
				PathElement[] children = new PathElement[entries.length];
				
				for (int i = 0; i < children.length; i++)
				{
					children[i] = new PathElement(pe, entries[i]);
				}
				
				return children;
			}
//			else if (element instanceof SyndEntry)
//			{
//				SyndEntry entry = (SyndEntry)element;
//				
//				entry.
//			}
			
			return new Object[0];
		}
		
		public Object getParent(Object element)
		{
			if (element == null)
				return null;
			else
				return ((PathElement)element).getParent();
		}
		
		public boolean hasChildren(Object element)
		{
			return getChildren(element).length > 0;
		}
		
		public Object[] getElements(Object inputElement)
		{
			return ((List)inputElement).toArray();			
		}
		
		public void dispose()
		{
			
		}
		
		public void inputChanged(Viewer viewer, Object oldInput, Object newInput)
		{
			
		}
	}
	
	static class PathElement
	{
		private PathElement parent;
		private Object 		data;
		
		
		public PathElement(Object data)
		{
			this.data = data;
		}
		
		public PathElement(PathElement parent, Object data)
		{
			this.parent = parent;
			this.data = data;
		}
		
		public PathElement getParent()
		{
			return parent;
		}

		public Object getData()
		{
			return data;
		}
		
		public String toString()
		{
			return data.toString();
		}
	}
	
	static class FeedLabelProvider
		extends LabelProvider
		implements IColorProvider, IFontProvider
	{
		
		public Image getImage(Object element)
		{
			PathElement pe = (PathElement)element;
			
			if (pe.getData() instanceof SyndEntry)
			{
				if (isCompleted(element))
					return TaDoPlugin.getImage("resources/icons/brkp_obj.gif");
				else
					return TaDoPlugin.getImage("resources/icons/brkpd_obj.gif");
			}
			else if (pe.getData() instanceof SyndFeed)
			{
				return TaDoPlugin.getImage("resources/icons/singleOrientation.gif");
			}
			else
			{
				return null;
			}
		}
		
		public String getText(Object element)
		{
			String str = getText_(element);
			
			if (str.startsWith("Completed:"))
			{
				return str.substring("Completed:".length()).trim();
			}
			else if (str.startsWith("Added:"))
			{
				return str.substring("Added:".length()).trim();
			}
			else if (str.endsWith("(Ta-da list)"))
			{
				return str.substring(0, str.length() - "(Ta-da list)".length()).trim();
			}
			
			return str;
		}
		
		private String getText_(Object element)
		{
			PathElement pe = (PathElement)element;
			
			if (pe.getData() instanceof SyndEntry)
			{
				SyndEntry entry = (SyndEntry)pe.getData();
				
				return entry.getTitle();
			}
			else if (pe.getData() instanceof SyndFeed)
			{
				SyndFeed feed = (SyndFeed)pe.getData();
				
				return feed.getTitle();
			}
			
			return "";
		}
		
		private boolean isCompleted(Object element)
		{
			String text = getText_(element);
			
			if (text != null && text.startsWith("Completed:"))
			{
				return true;
			}
			
			return false;
		}
		
		public Color getBackground(Object element)
		{
			return null;
		}
		
		public Color getForeground(Object element)
		{
			//if (isCompleted(element))
			//	return Display.getDefault().getSystemColor(SWT.COLOR_DARK_GRAY);
			
			return null;
		}

		public Font getFont(Object element)
		{
			if (isCompleted(element))
				return JFaceResources.getFontRegistry().getItalic(JFaceResources.DEFAULT_FONT);
			
			return null;
		}
	}
	
}
